package com.zbkj.service.model.front.vo.user;

import com.zbkj.dal.base.enums.UserIdentityEnums;
import com.zbkj.dal.common.utils.MoneyUtil;
import com.zbkj.dal.entity.fund.UserFundAccount;
import com.zbkj.dal.entity.merchant.MerchantEmployee;
import com.zbkj.dal.entity.system.SystemUserLevel;
import com.zbkj.dal.entity.user.EmployeeAccount;
import com.zbkj.dal.entity.user.User;
import com.zbkj.service.model.front.vo.fund.UserQuotaVO;
import com.zbkj.service.model.front.vo.fund.QuotaLevelVO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Objects;
import java.util.Optional;

@Data
@ApiModel
public class UserInfoVO {

    @ApiModelProperty(value = "用户昵称", example = "XY")
    private String nickName;

    @ApiModelProperty(value = "用户头像", example = "https://hq-bbsh.oss-cn-hangzhou.aliyuncs.com/crmebimage/public/product/2023/07/19/d5e0bd321a164707861bad5ccc26adc4uw4ws82r28.png")
    private String avatar;

    @ApiModelProperty("下一级额度信息")
    private UserQuota userQuota;

    @ApiModelProperty("等级额度信息")
    private QuotaLevelVO quotaLevelVO;

    @ApiModelProperty("雅识账户信息")
    private UserFundVO userFundVO;

    @ApiModelProperty("用户身份")
    private String userIdentity;

    @ApiModelProperty("用户身份描述")
    private String userIdentityDesc;

    @ApiModelProperty("用户工号")
    private String employeeNo;

    @ApiModelProperty("是否开卡")
    private Boolean isPartnerRole;

    @ApiModelProperty("用户卡号")
    private String cardNo;

    @Data
    @ApiModel
    public static class UserFundVO {

        @ApiModelProperty(value = "可用雅识金额", example = "100,000.00")
        private String availableAmount;
    }

    @Data
    @ApiModel
    @EqualsAndHashCode(callSuper = true)
    public static class UserQuota extends UserQuotaVO {

        @ApiModelProperty(value = "距离下一级额度", example = "20,000.00")
        private String nextLevelGap;

        @ApiModelProperty(value = "下一等级", example = "8")
        private Integer nextLevel;

        @ApiModelProperty(value = "下一级进度", example = "0.80")
        private BigDecimal nextLevelProgress;

        @ApiModelProperty(value = "已用进度", example = "0.30")
        private BigDecimal usedProgress;
    }


    public static UserInfoVO generate(User user, UserQuotaVO userQuotaVO, UserFundAccount userFundAccount, SystemUserLevel currentLevel, SystemUserLevel nextLevel, EmployeeAccount employeeAccount, MerchantEmployee merchantEmployee) {
        UserQuota userQuotaInfo = new UserQuota();
        QuotaLevelVO quotaLevel = new QuotaLevelVO();
        if (Objects.nonNull(nextLevel)) {
            String nextLevelGap = Optional.of(nextLevel).map(level -> level.getLimitDown().subtract(userQuotaVO.getTotalQuotaOriginal()))
                    .map(quota -> quota.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : quota).map(MoneyUtil::prettyFormat).orElse("0.00");
            userQuotaInfo.setNextLevelGap(nextLevelGap);
        } else {
            userQuotaInfo.setNextLevelGap("0.00");
        }
        UserFundVO userFundVO = new UserFundVO();
        if (Objects.nonNull(userFundAccount)) {
            userFundVO.setAvailableAmount(MoneyUtil.prettyFormat(userFundAccount.getAvailableAmount()));
        } else {
            userFundVO.setAvailableAmount(MoneyUtil.prettyFormat(BigDecimal.ZERO));
        }
        userQuotaInfo.setMemberLevel(currentLevel.getGrade());
        userQuotaInfo.setLevelId(userQuotaVO.getLevelId());
        userQuotaInfo.setLevelDesc(currentLevel.getName());
        userQuotaInfo.setTotalQuota(userQuotaVO.getTotalQuota());
        userQuotaInfo.setUsedQuota(userQuotaVO.getUsedQuota());
        userQuotaInfo.setAvailableQuota(userQuotaVO.getAvailableQuota());
        userQuotaInfo.setTotalQuotaOriginal(userQuotaVO.getTotalQuotaOriginal());
        userQuotaInfo.setUsedQuotaOriginal(userQuotaVO.getUsedQuotaOriginal());
        userQuotaInfo.setAvailableQuotaOriginal(userQuotaVO.getAvailableQuotaOriginal());
        quotaLevel.setMemberLevel(currentLevel.getGrade());
        quotaLevel.setLevelDesc(currentLevel.getName());
        quotaLevel.setMinQuota(MoneyUtil.prettyFormat(currentLevel.getLimitDown()));
        quotaLevel.setMaxQuota(MoneyUtil.prettyFormat(currentLevel.getLimitUp()));

        if (Objects.equals(nextLevel.getId(), userQuotaVO.getMemberLevel())) {
            BigDecimal usedProgress = userQuotaVO.getUsedQuotaOriginal().multiply(BigDecimal.valueOf(100)).divide(userQuotaVO.getTotalQuotaOriginal(), 2, RoundingMode.DOWN);
            userQuotaInfo.setNextLevelProgress(BigDecimal.valueOf(100).setScale(2, RoundingMode.DOWN));
            userQuotaInfo.setUsedProgress(usedProgress);
//            userQuotaInfoVO.setNextLevel(userQuotaVO.getMemberLevel());
        } else {
            BigDecimal nextLevelProgress = nextLevel.getLimitDown().compareTo(userQuotaVO.getTotalQuotaOriginal()) <= 0 ? BigDecimal.valueOf(100) :
                    userQuotaVO.getTotalQuotaOriginal().multiply(BigDecimal.valueOf(100)).divide(nextLevel.getLimitDown(), 2, RoundingMode.DOWN);
            BigDecimal usedProgress = userQuotaVO.getUsedQuotaOriginal().multiply(BigDecimal.valueOf(100)).divide(nextLevel.getLimitDown(), 2, RoundingMode.DOWN);
            userQuotaInfo.setNextLevelProgress(nextLevelProgress);
            userQuotaInfo.setUsedProgress(usedProgress);
            userQuotaInfo.setNextLevel(Optional.of(nextLevel).map(SystemUserLevel::getGrade).orElse(userQuotaVO.getMemberLevel()));
        }

        UserInfoVO userInfoVO = new UserInfoVO();
        userInfoVO.setUserQuota(userQuotaInfo);
        userInfoVO.setQuotaLevelVO(quotaLevel);
        userInfoVO.setNickName(user.getNickname());
        userInfoVO.setAvatar(user.getAvatar());
        userInfoVO.setUserFundVO(userFundVO);
        userInfoVO.setIsPartnerRole(user.getIsPartnerRole());
        userInfoVO.setCardNo(user.getPartnerRoleCode());
        if (Objects.nonNull(employeeAccount)) {
            userInfoVO.setEmployeeNo(employeeAccount.getEmployeeNo());
        }
        if (Objects.nonNull(merchantEmployee)) {
            userInfoVO.setUserIdentity(merchantEmployee.getIdentity());
            userInfoVO.setUserIdentityDesc(UserIdentityEnums.getDescByCode(merchantEmployee.getIdentity()));
            userInfoVO.setEmployeeNo(merchantEmployee.getEmployeeNo());
        }
        return userInfoVO;
    }
}
